/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mainclasses;

import ruter.map.AnonymousMapComponent;
import ruter.map.Map;
import ruter.visual.Painter;
import ruter.visual.RoundBall;
import ruter.simulator.Simulation;
import ruter.simulator.Vehicle;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Iterator;
import java.util.Random;

import components.RobotPilot;
import ruter.network.AdhocNetwork;
import ruter.network.Node;
import ruter.network.UnavailableInformationException;
import visualkey.KCanvas;

/**
 *
 * @author camilo
 */
public class NoRules extends KCanvas implements KeyListener {

	public static final int[] MAP_DIMENSION = {1000, 600};
	public static final int NODE_RADIUS = 90;
	public static final int NUMBER_OF_ROBOTS = 8;
	public static final long FRAME_TIME = Simulation.ACCURACY_HIGH;
	public static final int MAX_PPM = 10;
	public static final int MIN_PPM = 1;

	public static int ppm = 5; // Pixels per meter

	private Map map;
	private AdhocNetwork network;
	private Simulation simulation;
	private boolean findOrNot = false, allFind = false;

	public static void main(String args[]) {
		NoRules test = new NoRules();
		test.setDefaultCloseOperation(test.EXIT_ON_CLOSE);
		test.setVisible(true);
	}

	public NoRules() {
		super(new Dimension(MAP_DIMENSION[0] * ppm + 10, MAP_DIMENSION[1] * ppm + 20));
		createMainInstances();
		addRobots();
		addKeyListener(this);
		simulation.start();
		updateScreen(false);
	}

	public void createMainInstances() {

		// Map
		map = new Map(MAP_DIMENSION[0], MAP_DIMENSION[1], Double.MAX_VALUE);

		// Network
		network = new AdhocNetwork(NODE_RADIUS);

		// Simulation
		simulation = new Simulation(this, map, network, FRAME_TIME);
	}

	private void addRobots() {
		Random random = new Random();
		AnonymousMapComponent target = new AnonymousMapComponent(map.getXBounds()/2, map.getYBounds()/2);
		for (int i = 0; i < NUMBER_OF_ROBOTS; i++) {
			Vehicle v = new Vehicle(10 + i * 5, 10, 2, 1, 1, 180);
			RobotPilot pilot = new RobotPilot(map, target, FRAME_TIME/1000d,simulation);
			pilot.setUseRules(false);
			v.putDriver(pilot);
			v.putMap(map);
			v.addAccesory(new RoundBall(network.getMinimumDistanceConnection()));
			network.addNode(pilot);
			simulation.addVehicle(v, new Color(random.nextInt()));
		}
	}

	@Override
	protected void paintCanvas(Graphics g) {

		simulation.repaint(g, ppm);
		firstToFind();

		// Painting pointing dots
		g.setColor(Color.red);
		for (int i = 0; i < simulation.getVehicles().size(); i++) {
			RobotPilot rp = (RobotPilot) simulation.getVehicles().get(i).getDriver();
			g.fillOval((int)rp.objective.x*ppm-2, (int)rp.objective.y*ppm-2, 4, 4);
		}
	}

	private void firstToFind(){
		int robotsFoundTarget = 0;
		for (int i = 0; i < simulation.getVehicles().size(); i++) {
			RobotPilot robot = (RobotPilot) simulation.getVehicles().get(i).getDriver();
			if(robot.getTimeToFind()!=0){
				if(!findOrNot) {
					System.out.println(""+(robot.getTimeToFind()/1000d));
					findOrNot = true;
				}
				robotsFoundTarget ++;
			}
		}
		if(simulation.getVehicles().size() == robotsFoundTarget && !allFind) {
			System.out.println(""+(simulation.getRealTime()/1000d));
			allFind = true;
		}
	}

	public void updateScreen(boolean requestScreenAdjust) {
		super.setTitle("Ruter - PPM: " + ppm + " - speed: " + (simulation.getSimulationSpeed() > 1 ? "1/" + (int) simulation.getSimulationSpeed() + "x" : (int) (1 / simulation.getSimulationSpeed()) + "x"));
		if (requestScreenAdjust) {
			modifyCanvasSize(new Dimension(MAP_DIMENSION[0] * ppm + 10, MAP_DIMENSION[1] * ppm + 20));
		}
	}

	@Override
	public void keyPressed(KeyEvent e) {
		switch (e.getKeyCode()) {
		case KeyEvent.VK_UP:
			if (ppm < MAX_PPM) {
				ppm++;
				updateScreen(true);
				repaint();
			}
			break;
		case KeyEvent.VK_DOWN:
			if (ppm > MIN_PPM) {
				ppm--;
				updateScreen(true);
				repaint();
			}
			break;
		case KeyEvent.VK_RIGHT:
			simulation.increaseSimulationSpeed();
			updateScreen(false);
			break;
		case KeyEvent.VK_LEFT:
			simulation.decreaseSimulationSpeed();
			updateScreen(false);
			break;
		}
		
		switch (e.getKeyChar()) {

		case 'a':
			System.out.println("Number of groups: "+network.numberOfSubnets());
			break;

		case 'p':
			simulation.pauseSimulation();
			break;

		case 'r':
			simulation.resumeSimulation();
			break;

		case 's':
			simulation.stopSimulation();
			break;

		case 't':
			System.out.println("Time: "+simulation.getRealTime());
			break;
		}
		
	}

	@Override
	public void keyTyped(KeyEvent e) {}

	@Override
	public void keyReleased(KeyEvent e) {}

}
